package com.d3works.apps.account.db.repo;

import com.d3works.apps.account.db.Invoice;
import com.d3works.apps.account.db.InvoicePayment;
import com.d3works.apps.account.db.SubrogationRelease;
import com.d3works.apps.account.service.invoice.InvoiceService;
import com.d3works.apps.account.service.invoice.InvoiceToolService;
import com.d3works.exception.service.TraceBackService;
import com.d3works.inject.Beans;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import javax.persistence.PersistenceException;
import org.apache.commons.collections.CollectionUtils;

public class InvoiceManagementRepository extends InvoiceRepository {
  @Override
  public Invoice copy(Invoice entity, boolean deep) {
    try {
      Invoice copy = super.copy(entity, deep);

      InvoiceToolService.resetInvoiceStatusOnCopy(copy);
      return copy;
    } catch (Exception e) {
      throw new PersistenceException(e);
    }
  }

  @Override
  public Invoice save(Invoice invoice) {
    try {
      List<InvoicePayment> invoicePayments = invoice.getInvoicePaymentList();
      if (CollectionUtils.isNotEmpty(invoicePayments)) {
        LocalDate latestPaymentDate =
            invoicePayments.stream()
                .filter(
                    invoicePayment ->
                        invoicePayment.getStatusSelect()
                            == InvoicePaymentRepository.STATUS_VALIDATED)
                .map(InvoicePayment::getPaymentDate)
                .max(LocalDate::compareTo)
                .orElse(null);
        invoice.setPaymentDate(latestPaymentDate);
      }
      invoice = super.save(invoice);

      InvoiceService invoiceService = Beans.get(InvoiceService.class);
      invoiceService.setDraftSequence(invoice);

      return invoice;
    } catch (Exception e) {
      TraceBackService.traceExceptionFromSaveMethod(e);
      throw new PersistenceException(e.getMessage(), e);
    }
  }

  @Override
  public Map<String, Object> populate(Map<String, Object> json, Map<String, Object> context) {
    try {
      final String subrogationStatusSelect = "$subrogationStatusSelect";
      if (context.get("_model") != null
          && context.get("_model").toString().equals(SubrogationRelease.class.getName())) {
        if (context.get("id") != null) {
          long id = (long) context.get("id");
          SubrogationRelease subrogationRelease =
              Beans.get(SubrogationReleaseRepository.class).find(id);
          if (subrogationRelease != null && subrogationRelease.getStatusSelect() != null) {
            json.put(subrogationStatusSelect, subrogationRelease.getStatusSelect());
          } else {
            json.put(subrogationStatusSelect, SubrogationReleaseRepository.STATUS_NEW);
          }
        }
      } else {
        json.put(subrogationStatusSelect, SubrogationReleaseRepository.STATUS_NEW);
      }
    } catch (Exception e) {
      TraceBackService.trace(e);
    }

    return super.populate(json, context);
  }
}
